package test.org.cedar.syntaxcore;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import junit.framework.TestCase;

import org.cedar.exceptions.CalcException;
import org.cedar.exceptions.VariantIOException;
import org.cedar.syntaxcore.Calculator;
import org.cedar.syntaxcore.FormulaUtil;
import org.cedar.syntaxcore.FunctionIntf;
import org.cedar.syntaxcore.Parser;
import org.cedar.syntaxcore.SyntaxContext;
import org.cedar.syntaxcore.VariantContext;

public class CedarFormularTst extends TestCase {
	private FormulaUtil util;

	protected void setUp() throws Exception {
		util = new FormulaUtil();
	}

	protected void tearDown() throws Exception {
		util = null;
	}

	public void testCal() {
		try {
			util.execute("print(true|false&true)");
		} catch (CalcException e) {
			e.printStackTrace();
		}
	}

	public void testCtx() throws CalcException {
		SyntaxContext vCtx = new SyntaxContext();
		final Hashtable<Object, Object> tb = new Hashtable<Object, Object>();
		tb.put("abc", "v");
		vCtx.setDataSource(new VariantContext() {
			@Override
			public Map<Object, Object> getAll() throws VariantIOException {
				// TODO Auto-generated method stub
				return null;
			}
			@Override
			public boolean containVariant(String variantName) {
				return tb.contains(variantName);
			}

			public Object get(String variantName)
					throws VariantIOException {
				return tb.get(variantName);
			}

			public Object get(String variantName, List params)
					throws VariantIOException {
				return tb.get(variantName);
			}

			public void put(String variantName, List params,
					Object variantValue) throws VariantIOException {
				tb.put(variantName, variantValue);
			}

			public void put(String variantName, Object variantValue)
					throws VariantIOException {
				tb.put(variantName, variantValue);
			}
		});
		Calculator cal = new Calculator(vCtx);
		Parser parser = new Parser();
		//stage 1
		parser.parseIt("print(!isEmpty([abc]));");
		cal.calcIt(parser.eqResult);
		//stage 2
		parser.parseIt("[metas.won] = decode(isEmpty([abc])&isEmpty([abcd]),'true',decode(isEmpty([abcf]),'true','vvvvvvvvv','abcddd'),'bad!')");
		cal.calcIt(parser.eqResult);
		System.out.println("1::"+tb.get("metas.won"));
		tb.put("abc", "");
		//stage 3
		cal.calcIt(parser.eqResult);
		System.out.println("2::"+tb.get("metas.won"));
		cal = null;
		parser = null;
	}
    public void testCaseWhen(){
    	
    }
	public void testProcessString() {
		    	try {
		    		SyntaxContext ctx = new SyntaxContext();
		    		FormulaUtil util = new FormulaUtil(ctx);
		    		ctx.registerFunction("addRank", new FunctionIntf(){
		    			@Override
		    			public Object execute(List parameters) {
		    				return "Zzz! call function 'addRank' complete";
		    			}
		    		});
					util.execute("if( LENGTH(\"2\")>0){print(addRank(999))/* 注释 */}");
					util.execute("[abc]='abc';[abc]=[abc]+','+1000+',';print(substring([abc],0,length([abc])-1));");
				} catch (CalcException e) {
					e.printStackTrace();
				}
	}
	
	public void testList(){
    		SyntaxContext ctx = new SyntaxContext();
    		FormulaUtil util = new FormulaUtil(ctx);
    		ctx.registerFunction("addRank", new FunctionIntf(){
    			@Override
    			public Object execute(List parameters) {
    				return "Zzz! call function 'addRank' complete";
    			}
    		});
    		ctx.put("metas.wzh", "abc");
    		//ctx.put("IS_A", true);
    		ArrayList<String> synLst = new ArrayList<String>();
    		synLst.add("[metas.wonn] = 0;");
    		synLst.add("[metas.wonn2] = 97.0;");
    		synLst.add("[metas.wonn3] = [metas.wonn2]");
    		synLst.add("[metas.wonn1] = \"a\";");
    		synLst.add("[metas.wonn1] = [metas.wonn1] +100/*隐式转换*/+33+',';");
//    		synLst.add("if( LENGTH([metas.wonn])>1){print(addRank(1));/* 注释 */print([metas.wonn]);}else{print(addRank(0))}");
//    		synLst.add("if(!isEmpty([metas.wonn])){print('TTTTTTTTTTTT');print('asdfasfdasf');if isEmpty([metas.wonn1]){print([metas.wonn1])}else if 1==1 {print('bbbbbbbbb')}else{print('aaaaaaaaaaaa')}}");
//    		synLst.add("if [IS_A]==true{print('IS_A');}");
    		synLst.add("print([metas.wonn1]);");
    		synLst.add("print([metas.wonn3]);");
           
    	try {
			util.process(synLst);
			//System.out.println(fillDescription("fff[metas.wonn]'s name is not empty",ctx));
			//System.out.println(ctx.get("metas.wonn"));
			//util.process(new File("e:\\syntax.txt"));
		} catch (CalcException e) {
			e.printStackTrace();
		}
	}
	String fillDescription(String src, SyntaxContext ctx) {
        StringBuilder sb = new StringBuilder();
        int sz = src.length();
        int i = 0;
        StringBuilder varNm = new StringBuilder();
        while (i < sz) {
            char c = src.charAt(i);
            if ('[' == c) {
                int pairCnt = 1;
                i++;
                varNm.setLength(0);
                while (i < sz) {
                    if (pairCnt == 0)
                        break;
                    c = src.charAt(i);
                    if (c == '[')
                        pairCnt++;
                    else if (c == ']')
                        pairCnt--;
                    else
                        varNm.append(c);
                    i++;
                }
                if (varNm.length() > 0) {
                    sb.append(ctx.get(varNm.toString()));
                }
            } else{
                sb.append(c);
                i++;
            }
        }
        return sb.toString();
    }
	public void testFile()throws Exception{
		try {
			SyntaxContext ctx = new SyntaxContext();
			FormulaUtil util = new FormulaUtil(ctx);
			ctx.registerFunction("addRank", new FunctionIntf(){
				@Override
				public Object execute(List parameters) {
					return "Zzz! call function 'addRank' complete";
				}
			});
			util.process(new File("e:\\syntax13.txt"));
		} catch (CalcException e) {
			e.printStackTrace();
		}
	}
	public void testCommander()throws Exception{
		SyntaxContext ctx = new SyntaxContext();
		FormulaUtil util = new FormulaUtil(ctx);
		CommanderTest ct = new CommanderTest();
		ctx.registerCommander(ct);
		util.execute("[a]=100;[b]=2;test1([a],''+[b]);print('RETURN of test2>>'+test2([a],[b]+'',100L));test3(#2009-10-14);test4(343.4422);test4(3333D/33);test5([a]%[b],100/20)");
	}
	public void testWhileClause()throws Exception{
		long curr = System.currentTimeMillis();
		SyntaxContext ctx = new SyntaxContext();
		FormulaUtil util = new FormulaUtil(ctx);
		ctx.put("cond", 0);
		util.execute("while([cond]<100000){[cond]=[cond]+1;print('cond>>'+[cond]);if([cond]%35 == 0){print('now times of 35');}}");
		System.out.println("Time spent: "+ (System.currentTimeMillis() - curr));
	}
	public static void main(String[] args)throws Exception{
		 SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		 System.out.println(simpleDateFormat.parse("2009-10-13 15:33:22"));
		 System.out.println(simpleDateFormat.parse("2009-10-14"));
//		System.out.println("a"+"\r\nuuujjj{}\r\n".replaceAll("(^[\\s\\r\\n]+)|([\\s\\r\\n]+$)/g", "")+"b");
	}

	public void testJavaWhileLoop(){
		long curr = System.currentTimeMillis();
		int l = 0;
		while(l < 100000){
			l+=1;
			if(l%35 == 0)
				System.out.println("times of 35 now!");
		}
		System.out.println("Time spent: "+ (System.currentTimeMillis() - curr));
	}
	public void getUserLanguage(){
		System.out.println(System.getProperty("user.language"));
	}
}
